#include "fileServer.h"
#include <fstream>
#include <sstream>

#include "tinyxml.h"
#include "object.h"

namespace sde {

    FileServer::FileServer() {
    }
    
    bool FileServer::hasFileType(std::string ext) {
        return filesByType.find(ext) != filesByType.end();
    }
    
    StringList FileServer::getFilesByType(std::string ext) {
        if (hasFileType(ext))
            return filesByType[ext];
        else
            return StringList();
    }
    
    bool FileServer::hasFileName(std::string name) {
        return filesByName.find(name) != filesByName.end();
    }
    
    std::string FileServer::getFileByName(std::string name) {
        return filesByName[name];
    }
    
    std::string FileServer::getType(std::string file) {
        size_t pos = file.find('.');
        if (pos != std::string::npos)
            return file.substr(pos+1);
        else
            return "";
    }
    
    std::string FileServer::getName(std::string file) {
        return file.substr(file.find_last_of('/')+1);
    }
    
    StringList FileServer::enumerateFiles(std::string path) {
        StringList files;
        
        folders.push_back(path);
        
        boost::python::object pyFiles = Object::glob(path + "/*");
        int len = boost::python::extract<int>(pyFiles.attr("__len__")());
        for (int i = 0; i < len; ++i) {
            boost::python::object pyFile = pyFiles.attr("__getitem__")(i);
            std::string path = boost::python::extract<std::string>(pyFile);
            if (Object::osPath.attr("isfile")(pyFile)) {
                files.push_back(path);
            } else if (Object::osPath.attr("isdir")(pyFile)) {
                StringList subFiles = enumerateFiles(path);
                for (StringList::iterator j = subFiles.begin(); j != subFiles.end(); ++j)
                    files.push_back(*j);
            }
        }
        
        return files;
    }
    
    void FileServer::loadModules(int argc, char** argv) {
        for (int i = 1; i < argc; ++i) {
            std::string module(argv[i]);
        
            modules.push_back(module);
            
            StringList files = enumerateFiles(module);
            
            for (StringList::iterator i = files.begin(); i != files.end(); ++i) {
                std::string fileType = getType(*i);
                std::string fileName = getName(*i);
                
                fileTypes.remove(fileType);
                fileTypes.push_back(fileType);
                
                filesByName[fileName] = *i;
                
                if (filesByType.find(fileType) == filesByType.end())
                    filesByType[fileType] = StringList();
                filesByType[fileType].push_back(*i);
            }
        }
    }
    
    void FileServer::loadSimFiles() {
        if (filesByType.find("sim") != filesByType.end()) {
            for (StringList::iterator i = filesByType["sim"].begin(); i != filesByType["sim"].end(); ++i) {
                
                TiXmlDocument doc(i->c_str());
                if (doc.LoadFile()) {
                    printf("load sim %s\n",i->c_str());
                    TiXmlElement* objectElement = doc.FirstChildElement("object");
                    while (objectElement) {
                        const char* cName = objectElement->Attribute("name");
                        std::string name;
                        if (cName) 
                            name = cName;
                        else
                            name = "object";
                            
                        printf("object %s\n",name.c_str());
                        
                        Object* object = new Object(name);
                        object->load(objectElement);
                            
                        objectElement = objectElement->NextSiblingElement("object");
                    }
                } else
                    printf("ERROR: couldn't load sim %s\n",i->c_str());
            }
        }
    }
}
